package com.winning.common.data.dao;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;

import com.framework.helper.ServerSQLExecutorUtils;
import com.framework.server.db.inter.IResultHandler;
import com.framework.server.manager.LocalServiceLocatorManager;
import com.winning.common.beans.xmlTemp.XMLTempConfigBean;

/**
 * 类名称：AppBaseService 类描述：数据库基础服务类 创建人：liuwensheng 创建时间：2016-10-8 上午10:55:32
 * 修改人：liuwensheng 修改时间：2016-10-8 上午10:55:32 修改备注：
 */
public class AppBaseDao {
    private static Logger LOGGER = Logger.getLogger("pbsLoger");

    public static final String EXEC_SQL_TYPE = "sql";

    public static final String EXEC_PROC_SQL_TYPE = "procSQL";

    /**
     * 执行普通sql和存储过程的查询接口封装，返回JSONObject列表 方法名称: executeQueryReturnMapList
     *
     * @param sql
     * @param params
     * @param sqlType
     * @param dbType
     * @return List<JSONObject> 返回类型说明
     * @author liuwensheng@winning.com.cn<br/>
     * 创建时间：2016-9-22/下午8:58:04<br/>
     */
    public List<Map<String, Object>> executeQueryReturnMapList(String sql, Object[] params) {
        List<Map<String, Object>> rowValueList = new ArrayList<Map<String, Object>>();

        try {
            ResultSet rs = null;

            if (params == null) {
                rs = ServerSQLExecutorUtils.executeQuery(sql);
            } else {
                rs = ServerSQLExecutorUtils.executeQuery(sql, params);
            }

            if (rs != null) {
                rs.beforeFirst();

                ResultSetMetaData rsmd = rs.getMetaData();

                // 列的数量
                int columnCount = rsmd.getColumnCount();

                while (rs.next()) {
                    // 一行数据
                    Map<String, Object> rowDataObjMap = new HashMap<String, Object>();

                    // 循环一行数据，取出所有的列
                    for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
                        // 列的名称, 统一转成大写
                        String columnNameStr = rsmd.getColumnName(columnIndex + 1).toUpperCase();

                        // 列的值
                        Object columnValueObj = rs.getObject(columnNameStr);

                        rowDataObjMap.put(columnNameStr, columnValueObj);
                    }

                    // 保存行数据集
                    rowValueList.add(rowDataObjMap);
                }

                LOGGER.info("--> SQL执行结束：成功, 总共[" + rowValueList.size() + "]条记录");

                // 结果集关闭
                rs.close();
            }
        } catch (Exception e) {
            LOGGER.error("--> 查询SQL出现异常，SQL:" + sql);
            // 打印异常堆栈信息
            LOGGER.error(e, e.fillInStackTrace());
            e.printStackTrace();
        }

        return rowValueList;
    }

    /**
     * 执行普通sql和存储过程的查询接口封装，返回JSONObject列表 方法名称:
     * executeQueryReturnMapListByDataSource
     *
     * @param sql
     * @param params
     * @param dataSourceID 指定数据源
     * @return List<HashMap                                                                                                                               <                                                                                                                               String                                                                                                                               ,                                                                                                                                                                                                                                                               Object>> 返回类型说明
     * @author liuwensheng@winning.com.cn<br/>
     * 创建时间：2016-9-22/下午8:58:04<br/>
     */
    public List<HashMap<String, Object>> executeQueryReturnMapListByDataSource(String sql, Object[] params,
                                                                               String dataSourceID) {
        List<HashMap<String, Object>> rowValueList = new ArrayList<HashMap<String, Object>>();

        try {
            if (params == null) {
                rowValueList = ServerSQLExecutorUtils.executeQuery(sql, dataSourceID);
            } else {
                rowValueList = ServerSQLExecutorUtils.executeQueryOtherDB(sql, params, dataSourceID);
            }

        } catch (Exception e) {
            LOGGER.error("--> 查询SQL出现异常，SQL:" + sql);
            // 打印异常堆栈信息
            LOGGER.error(e, e.fillInStackTrace());
            e.printStackTrace();
        }

        return rowValueList;
    }

    /**
     * 执行普通sql和存储过程的查询接口封装，返回JSONObject列表 方法名称:
     * executeQueryReturnJSONByDataSource
     *
     * @param
     * @return JSONObject 返回类型说明<br/>
     * @throws <br/>
     * @author zq@winning.com.cn<br/>
     * 创建时间：2017-1-7/下午7:29:27<br/>
     */
    public JSONObject executeQueryReturnJSONByDataSource(String sql, Object[] params, String dataSourceID) {
        List<HashMap<String, Object>> rowValueList = new ArrayList<HashMap<String, Object>>();

        try {
            if (params == null) {
                rowValueList = ServerSQLExecutorUtils.executeQuery(sql, dataSourceID);
            } else {
                rowValueList = ServerSQLExecutorUtils.executeQueryOtherDB(sql, params, dataSourceID);
            }

            if (rowValueList != null && rowValueList.size() > 0) {
                HashMap<String, Object> mp = rowValueList.get(0);

                JSONObject jsonObject = new JSONObject();

                for (Entry<String, Object> entity : mp.entrySet()) {
                    jsonObject.put(entity.getKey(), entity.getValue());
                }

                return jsonObject;
            }

        } catch (Exception e) {
            LOGGER.error("--> 查询SQL出现异常，SQL:" + sql);
            // 打印异常堆栈信息
            LOGGER.error(e, e.fillInStackTrace());
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 执行普通sql和存储过程的查询接口封装，返回JSONObject数组列表 方法名称:
     * executeQueryReturnJSONListByDataSource
     *
     * @param
     * @return List<JSONObject> 返回类型说明<br/>
     * @throws <br/>
     * @author zq@winning.com.cn<br/>
     * 创建时间：2017-1-7/下午7:34:12<br/>
     */
    public List<JSONObject> executeQueryReturnJSONListByDataSource(String sql, Object[] params, String dataSourceID) {

        List<JSONObject> jsonList = new ArrayList<JSONObject>();

        List<HashMap<String, Object>> rowValueList = new ArrayList<HashMap<String, Object>>();

        try {
            if (params == null) {

                rowValueList = ServerSQLExecutorUtils.executeQuery(sql, dataSourceID);

            } else {
                rowValueList = ServerSQLExecutorUtils.executeQueryOtherDB(sql, params, dataSourceID);
            }

            if (rowValueList != null) {

                for (HashMap<String, Object> mp : rowValueList) {

                    JSONObject jsonObject = new JSONObject();

                    for (Entry<String, Object> entity : mp.entrySet()) {
                        jsonObject.put(entity.getKey(), entity.getValue());
                    }

                    jsonList.add(jsonObject);
                }

            }

        } catch (Exception e) {
            LOGGER.error("--> 查询SQL出现异常，SQL:" + sql);
            // 打印异常堆栈信息
            LOGGER.error(e, e.fillInStackTrace());
            e.printStackTrace();
        }

        return jsonList;
    }

    /**
     * 执行普通sql和存储过程的查询接口封装，只返回单一JSON对象 方法名称: executeQueryReturnJSONObject
     *
     * @param sql
     * @param params
     * @param sqlType
     * @param dbType
     * @return JSONObject 返回单一JSON对象
     * @author liuwensheng@winning.com.cn<br/>
     * 创建时间：2016-9-22/上午11:05:25<br/>
     */
    @SuppressWarnings("unchecked")
    public JSONObject executeQueryReturnJSONObject(String sql, Object[] params, String sqlType, String dbType) {
        JSONObject jsonObjValue = null;

        try {
            // 结果集为JSONObject格式
            IResultHandler jsonResultHandler = (IResultHandler) LocalServiceLocatorManager.getInstance()
                    .getService(ServerSQLExecutorUtils.JSONFORMATRESULT);

            List<JSONObject> jsonTodayObjList = null;

            // 普通SQL
            if (EXEC_SQL_TYPE.equals(sqlType)) {
                jsonTodayObjList = (List<JSONObject>) ServerSQLExecutorUtils.executeQuery(sql, params,
                        jsonResultHandler);
            }
            // 存储过程
            else if (EXEC_PROC_SQL_TYPE.equals(sqlType)) {
                jsonTodayObjList = (List<JSONObject>) ServerSQLExecutorUtils.execProc(sql, params, dbType,
                        jsonResultHandler);
            }

            // 封装数据源
            if (jsonTodayObjList != null) {
                jsonObjValue = jsonTodayObjList.get(0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return jsonObjValue;
    }

    /**
     * 执行普通sql和存储过程的查询接口封装，返回JSONObject列表 方法名称: executeQueryReturnJSONObjectList
     *
     * @param sql
     * @param params
     * @param sqlType
     * @param dbType
     * @return List<JSONObject> 返回类型说明
     * @author liuwensheng@winning.com.cn<br/>
     * 创建时间：2016-9-22/下午8:58:04<br/>
     */
    @SuppressWarnings("unchecked")
    public List<JSONObject> executeQueryReturnJSONObjectList(String sql, Object[] params, String sqlType,
                                                             String dbType) {
        List<JSONObject> jsonTodayObjList = null;

        try {
            // 结果集为JSONObject格式
            IResultHandler jsonResultHandler = (IResultHandler) LocalServiceLocatorManager.getInstance()
                    .getService(ServerSQLExecutorUtils.JSONFORMATRESULT);

            // 普通SQL
            if (EXEC_SQL_TYPE.equals(sqlType)) {
                jsonTodayObjList = (List<JSONObject>) ServerSQLExecutorUtils.executeQuery(sql, params,
                        jsonResultHandler);
            }
            // 存储过程
            else if (EXEC_PROC_SQL_TYPE.equals(sqlType)) {
                jsonTodayObjList = (List<JSONObject>) ServerSQLExecutorUtils.execProc(sql, params, dbType,
                        jsonResultHandler);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return jsonTodayObjList;
    }
}
